summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamuel Rødal <samuel.rodal@nokia.com>2011-06-07 17:25:22 +0200
committerSamuel Rødal <samuel.rodal@nokia.com>2011-06-10 09:24:56 +0200
commitc58db2cd03d999d98bea3e961601668536ebc284 (patch)
treea5a45959d2d449a5e0ff7683f13e4929efee3cd6
parent172b24eebfbdf4aa989882c765f54f9dd5f92336 (diff)
QWindowContext / QWindowFormat refactor.
To enable having a single GL context used for multiple drawables we need to de-couple the context class a bit more from the window class in the plugin API. Now contexts are created stand-alone based on a GL format and a share context, and when calling makeCurrent() a desired surface is specified. This maps well to GLX, EGL, Cocoa, AGL, and WGL, which all support this use case. QWindowContext is renamed to QGuiGLContext, and QWindowFormat is renamed to QGuiGLFormat. We have the ability to introduce a pbuffer or similar other offscreen GL drawable abstraction in the future.
-rw-r--r--src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.h4
-rw-r--r--src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.cpp24
-rw-r--r--src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.h3
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.cpp7
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.h1
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.cpp111
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.h39
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.cpp5
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.h1
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.cpp60
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.h15
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.cpp118
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.h34
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.cpp5
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.h3
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp101
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.h20
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/xcomposite_egl.pri1
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.cpp117
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.h44
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.cpp7
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.h1
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.cpp91
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.h22
-rw-r--r--src/plugins/platforms/wayland/qwaylandintegration.cpp10
-rw-r--r--src/plugins/platforms/wayland/qwaylandintegration.h1
-rw-r--r--src/plugins/platforms/wayland/qwaylandshmwindow.cpp4
-rw-r--r--src/plugins/platforms/wayland/qwaylandshmwindow.h2
28 files changed, 486 insertions, 365 deletions
diff --git a/src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.h b/src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.h
index 250fdcc..2960d64 100644
--- a/src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.h
+++ b/src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.h
@@ -46,6 +46,9 @@ class QWaylandWindow;
class QWaylandDisplay;
class QWindow;
+class QPlatformGLContext;
+class QGuiGLFormat;
+
class QWaylandGLIntegration
{
public:
@@ -55,6 +58,7 @@ public:
virtual void initialize() = 0;
virtual QWaylandWindow *createEglWindow(QWindow *window) = 0;
+ virtual QPlatformGLContext *createPlatformGLContext(const QGuiGLFormat &glFormat, QPlatformGLContext *share) const = 0;
static QWaylandGLIntegration *createGLIntegration(QWaylandDisplay *waylandDisplay);
};
diff --git a/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.cpp b/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.cpp
index 57da38e..1d6e79e 100644
--- a/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.cpp
@@ -138,13 +138,14 @@ QWaylandGLWindowSurface::QWaylandGLWindowSurface(QWindow *window)
: QWindowSurface(window)
, mDisplay(QWaylandScreen::waylandScreenFromWindow(window)->display())
, mPaintDevice(0)
+ , mContext(0)
{
-
}
QWaylandGLWindowSurface::~QWaylandGLWindowSurface()
{
delete mPaintDevice;
+ delete mContext;
}
QPaintDevice *QWaylandGLWindowSurface::paintDevice()
@@ -152,31 +153,38 @@ QPaintDevice *QWaylandGLWindowSurface::paintDevice()
return mPaintDevice;
}
+QGuiGLContext *QWaylandGLWindowSurface::context() const
+{
+ if (!mContext)
+ const_cast<QGuiGLContext *&>(mContext) = new QGuiGLContext(window()->glFormat());
+ return mContext;
+}
+
void QWaylandGLWindowSurface::beginPaint(const QRegion &)
{
- window()->handle()->glContext()->makeCurrent();
- glClearColor(0,0,0,0xff);
+ context()->makeCurrent(window()->glSurface());
+ glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
}
-void QWaylandGLWindowSurface::flush(QWindow *window, const QRegion &region, const QPoint &offset)
+void QWaylandGLWindowSurface::flush(QWindow *, const QRegion &region, const QPoint &offset)
{
Q_UNUSED(offset);
Q_UNUSED(region);
-
+
if (mPaintDevice->isBound())
mPaintDevice->release();
QRect rect(0,0,size().width(),size().height());
- QGLContext *ctx = QGLContext::fromWindowContext(window->glContext());
+ QGLContext *ctx = QGLContext::fromGuiGLContext(context());
blitTexture(ctx,mPaintDevice->texture(),size(),mPaintDevice->size(),rect,rect);
- window->glContext()->swapBuffers();
+ context()->swapBuffers(window()->glSurface());
}
void QWaylandGLWindowSurface::resize(const QSize &size)
{
QWindowSurface::resize(size);
- window()->glContext()->makeCurrent();
+ context()->makeCurrent(window()->glSurface());
delete mPaintDevice;
mPaintDevice = new QGLFramebufferObject(size);
}
diff --git a/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.h b/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.h
index 31c0fd2..3703869 100644
--- a/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.h
+++ b/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.h
@@ -61,9 +61,12 @@ public:
void resize(const QSize &size);
+ QGuiGLContext *context() const;
+
private:
QWaylandDisplay *mDisplay;
QGLFramebufferObject *mPaintDevice;
+ QGuiGLContext *mContext;
};
#endif // QWAYLANDDRMSURFACE_H
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.cpp b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.cpp
index 50a1170..7fbe5cc 100644
--- a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.cpp
@@ -83,7 +83,12 @@ void QWaylandReadbackEglIntegration::initialize()
QWaylandWindow * QWaylandReadbackEglIntegration::createEglWindow(QWindow *window)
{
- return new QWaylandReadbackEglWindow(window,this);
+ return new QWaylandReadbackEglWindow(window, this);
+}
+
+QPlatformGLContext *QWaylandReadbackEglWindow::createPlatformGLContext(const QGuiGLFormat &glFormat, QPlatformGLContext *share) const
+{
+ return new QWaylandReadbackEglContext(glFormat, share, this);
}
EGLDisplay QWaylandReadbackEglIntegration::eglDisplay()
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.h b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.h
index 649f96e..8945cda 100644
--- a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.h
+++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.h
@@ -63,6 +63,7 @@ public:
void initialize();
QWaylandWindow *createEglWindow(QWindow *window);
+ QPlatformGLContext *createPlatformGLContext(const QGuiGLFormat &glFormat, QPlatformGLContext *share) const;
QWaylandDisplay *waylandDisplay() const;
Display *xDisplay() const;
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.cpp b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.cpp
index 5750c94..54b7d32 100644
--- a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.cpp
@@ -44,8 +44,19 @@
#include "qwaylandshmsurface.h"
#include "qwaylandreadbackglxwindow.h"
+#include <QtGui/QGuiGLContext>
#include <QtCore/QDebug>
+QWaylandReadbackGlxSurface::QWaylandReadbackGlxSurface(QWaylandReadbackGlxWindow *window)
+ : m_window(window)
+{
+}
+
+GLXPixmap QWaylandReadbackGlxSurface::glxPixmap() const
+{
+ return m_window->glxPixmap();
+}
+
static inline void qgl_byteSwapImage(QImage &img, GLenum pixel_type)
{
const int width = img.width();
@@ -68,94 +79,66 @@ static inline void qgl_byteSwapImage(QImage &img, GLenum pixel_type)
}
}
-QWaylandReadbackGlxContext::QWaylandReadbackGlxContext(QWaylandReadbackGlxIntegration *glxIntegration, QWaylandReadbackGlxWindow *window)
- : QPlatformGLContext()
- , mGlxIntegration(glxIntegration)
- , mWindow(window)
- , mBuffer(0)
- , mPixmap(0)
- , mConfig(qglx_findConfig(glxIntegration->xDisplay(),glxIntegration->screen(),window->widget()->platformWindowFormat(),GLX_PIXMAP_BIT))
- , mGlxPixmap(0)
+QWaylandReadbackGlxContext::QWaylandReadbackGlxContext(const QGuiGLFormat &format,
+ QPlatformGLContext *share, Display *display, int screen)
+ : m_display(display)
{
- XVisualInfo *visualInfo = glXGetVisualFromFBConfig(glxIntegration->xDisplay(),mConfig);
- mContext = glXCreateContext(glxIntegration->xDisplay(),visualInfo,0,TRUE);
+ GLXFBConfig config = qglx_findConfig(display, screen, format, GLX_PIXMAP_BIT);
- geometryChanged();
+ GLXContext shareContext = share ? static_cast<QWaylandReadbackGlxContext *>(share)->m_context : 0;
+
+ XVisualInfo *visualInfo = glXGetVisualFromFBConfig(display, config);
+ m_context = glXCreateContext(display, visualInfo, shareContext, TRUE);
+ m_format = qglx_guiGLFormatFromGLXFBConfig(display, config, m_context);
}
-void QWaylandReadbackGlxContext::makeCurrent()
+QGuiGLFormat QWaylandReadbackGlxContext::format() const
{
- glXMakeCurrent(mGlxIntegration->xDisplay(),mGlxPixmap,mContext);
+ return m_format;
+}
+
+bool QWaylandReadbackGlxContext::makeCurrent(const QPlatformGLSurface &surface)
+{
+ GLXPixmap glxPixmap = static_cast<const QWaylandReadbackGlxSurface &>(surface).glxPixmap();
+
+ return glXMakeCurrent(m_display, glxPixmap, m_context);
}
void QWaylandReadbackGlxContext::doneCurrent()
{
- QPlatformGLContext::doneCurrent();
+ glXMakeCurrent(m_display, 0, 0);
}
-void QWaylandReadbackGlxContext::swapBuffers()
+void QWaylandReadbackGlxContext::swapBuffers(const QPlatformGLSurface &surface)
{
- if (QWindowContext::currentContext().handle() != this) {
- makeCurrent();
- }
+ // #### makeCurrent() directly on the platform context doesn't update QGuiGLContext::currentContext()
+ if (QGuiGLContext::currentContext()->handle() != this)
+ makeCurrent(surface, surface);
- QSize size = mWindow->geometry().size();
+ const QWaylandReadbackGlxSurface &s =
+ static_cast<const QWaylandReadbackGlxSurface &>(surface);
- QImage img(size,QImage::Format_ARGB32);
+ QSize size = s.window()->geometry().size();
+
+ QImage img(size, QImage::Format_ARGB32);
const uchar *constBits = img.bits();
void *pixels = const_cast<uchar *>(constBits);
- glReadPixels(0,0, size.width(), size.height(), GL_RGBA,GL_UNSIGNED_BYTE, pixels);
+ glReadPixels(0, 0, size.width(), size.height(), GL_RGBA,GL_UNSIGNED_BYTE, pixels);
img = img.mirrored();
- qgl_byteSwapImage(img,GL_UNSIGNED_INT_8_8_8_8_REV);
+ qgl_byteSwapImage(img, GL_UNSIGNED_INT_8_8_8_8_REV);
constBits = img.bits();
- const uchar *constDstBits = mBuffer->image()->bits();
+ const uchar *constDstBits = s.window()->buffer();
uchar *dstBits = const_cast<uchar *>(constDstBits);
- memcpy(dstBits,constBits,(img.width()*4) * img.height());
-
-
- mWindow->damage(QRegion(QRect(QPoint(0,0),size)));
- mWindow->waitForFrameSync();
+ memcpy(dstBits, constBits, (img.width() * 4) * img.height());
+ s.window()->damage(QRect(QPoint(), size));
+ s.window()->waitForFrameSync();
}
-void * QWaylandReadbackGlxContext::getProcAddress(const QString &procName)
+void (*QWaylandReadbackGlxContext::getProcAddress(const QByteArray &procName)) ()
{
- return (void *) glXGetProcAddress(reinterpret_cast<GLubyte *>(procName.toLatin1().data()));
-}
-
-QPlatformWindowFormat QWaylandReadbackGlxContext::platformWindowFormat() const
-{
- return qglx_platformWindowFromGLXFBConfig(mGlxIntegration->xDisplay(),mConfig,mContext);
-}
-
-void QWaylandReadbackGlxContext::geometryChanged()
-{
- QSize size(mWindow->geometry().size());
- if (size.isEmpty()) {
- //QGLWidget wants a context for a window without geometry
- size = QSize(1,1);
- }
-
- mWindow->waitForFrameSync();
-
- delete mBuffer;
- //XFreePixmap deletes the glxPixmap as well
- if (mPixmap) {
- XFreePixmap(mGlxIntegration->xDisplay(),mPixmap);
- }
-
- mBuffer = new QWaylandShmBuffer(mGlxIntegration->waylandDisplay(),size,QImage::Format_ARGB32);
- mWindow->attach(mBuffer);
- int depth = XDefaultDepth(mGlxIntegration->xDisplay(),mGlxIntegration->screen());
- mPixmap = XCreatePixmap(mGlxIntegration->xDisplay(),mGlxIntegration->rootWindow(),size.width(),size.height(),depth);
- XSync(mGlxIntegration->xDisplay(),False);
-
- mGlxPixmap = glXCreatePixmap(mGlxIntegration->xDisplay(),mConfig,mPixmap,0);
-
- if (!mGlxPixmap) {
- qDebug() << "Could not make egl surface out of pixmap :(";
- }
+ return glXGetProcAddress(reinterpret_cast<const GLubyte *>(procName.constData()));
}
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.h b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.h
index 07e0f62..27a7287 100644
--- a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.h
+++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.h
@@ -43,6 +43,7 @@
#define QWAYLANDREADBACKGLXCONTEXT_H
#include <QPlatformGLContext>
+#include <QGuiGLFormat>
#include "qwaylandreadbackglxintegration.h"
@@ -51,29 +52,37 @@
class QWaylandReadbackGlxWindow;
class QWaylandShmBuffer;
+class QWaylandReadbackGlxSurface : public QPlatformGLSurface
+{
+public:
+ QWaylandReadbackGlxSurface(QWaylandReadbackGlxWindow *window);
+
+ QWaylandReadbackGlxWindow *window() const { return m_window; }
+ GLXPixmap glxPixmap() const;
+
+private:
+ QWaylandReadbackGlxWindow *m_window;
+};
+
class QWaylandReadbackGlxContext : public QPlatformGLContext
{
public:
- QWaylandReadbackGlxContext(QWaylandReadbackGlxIntegration *glxIntegration, QWaylandReadbackGlxWindow *window);
+ QWaylandReadbackGlxContext(const QGuiGLFormat &format, QPlatformGLContext *share, Display *display, int screen);
- void makeCurrent();
- void doneCurrent();
- void swapBuffers();
- void* getProcAddress(const QString& procName);
+ QGuiGLFormat format() const;
- QPlatformWindowFormat platformWindowFormat() const;
+ void swapBuffers(const QPlatformGLSurface &surface);
- void geometryChanged();
+ bool makeCurrent(const QPlatformGLSurface &surface);
+ void doneCurrent();
+
+ void (*getProcAddress(const QByteArray &procName)) ();
private:
- QWaylandReadbackGlxIntegration *mGlxIntegration;
- QWaylandReadbackGlxWindow *mWindow;
- QWaylandShmBuffer *mBuffer;
-
- Pixmap mPixmap;
- GLXFBConfig mConfig;
- GLXContext mContext;
- GLXPixmap mGlxPixmap;
+ GLXContext m_context;
+
+ Display *m_display;
+ QGuiGLFormat m_format;
};
#endif // QWAYLANDREADBACKGLXCONTEXT_H
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.cpp b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.cpp
index e17e3f8..6fb2a17 100644
--- a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.cpp
@@ -71,6 +71,11 @@ QWaylandWindow * QWaylandReadbackGlxIntegration::createEglWindow(QWindow *window
return new QWaylandReadbackGlxWindow(window,this);
}
+QPlatformGLContext *QWaylandReadbackGlxIntegration::createPlatformGLContext(const QGuiGLFormat &glFormat, QPlatformGLContext *share) const
+{
+ return new QWaylandReadbackGlxContext(glFormat, share, mDisplay, mScreen);
+}
+
QWaylandGLIntegration * QWaylandGLIntegration::createGLIntegration(QWaylandDisplay *waylandDisplay)
{
return new QWaylandReadbackGlxIntegration(waylandDisplay);
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.h b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.h
index 3055169..0b3d0cc 100644
--- a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.h
+++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.h
@@ -61,6 +61,7 @@ public:
void initialize();
QWaylandWindow *createEglWindow(QWindow *window);
+ QPlatformGLContext *createPlatformGLContext(const QGuiGLFormat &glFormat, QPlatformGLContext *share) const;
QWaylandDisplay *waylandDisplay() const;
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.cpp b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.cpp
index b70ed43..f878bef 100644
--- a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.cpp
@@ -39,12 +39,19 @@
**
****************************************************************************/
+#include <QtDebug>
+
#include "qwaylandreadbackglxwindow.h"
+#include "qwaylandshmsurface.h"
+
QWaylandReadbackGlxWindow::QWaylandReadbackGlxWindow(QWindow *window, QWaylandReadbackGlxIntegration *glxIntegration)
: QWaylandShmWindow(window)
- , mGlxIntegration(glxIntegration)
- , mContext(0)
+ , m_glxIntegration(glxIntegration)
+ , m_buffer(0)
+ , m_pixmap(0)
+ , m_config(qglx_findConfig(glxIntegration->xDisplay(), glxIntegration->screen(), window->glFormat()))
+ , m_glxPixmap(0)
{
}
@@ -54,20 +61,51 @@ QWaylandWindow::WindowType QWaylandReadbackGlxWindow::windowType() const
return QWaylandWindow::Egl;
}
-QPlatformGLContext * QWaylandReadbackGlxWindow::glContext() const
+void QWaylandReadbackGlxWindow::setGeometry(const QRect &rect)
{
- if (!mContext) {
- QWaylandReadbackGlxWindow *that = const_cast<QWaylandReadbackGlxWindow *>(this);
- that->mContext = new QWaylandReadbackGlxContext(mGlxIntegration,that);
+ QWaylandShmWindow::setGeometry(rect);
+
+ if (m_pixmap) {
+ delete mBuffer;
+ //XFreePixmap deletes the glxPixmap as well
+ XFreePixmap(m_glxIntegration->xDisplay(), m_pixmap);
+ m_pixmap = 0;
}
- return mContext;
}
-void QWaylandReadbackGlxWindow::setGeometry(const QRect &rect)
+GLXPixmap QWaylandReadbackGlxWindow::glxPixmap() const
{
- QWaylandShmWindow::setGeometry(rect);
+ if (!m_pixmap)
+ const_cast<QWaylandReadbackGlxWindow *>(this)->createSurface();
- if (mContext) {
- mContext->geometryChanged();
+ return m_glxPixmap;
+}
+
+uchar *QWaylandReadbackGlxWindow::buffer()
+{
+ return m_buffer->image()->bits();
+}
+
+void QWaylandReadbackGlxWindow::createSurface()
+{
+ QSize size(geometry().size());
+ if (size.isEmpty()) {
+ //QGLWidget wants a context for a window without geometry
+ size = QSize(1,1);
}
+
+ waitForFrameSync();
+
+ m_buffer = new QWaylandShmBuffer(m_glxIntegration->waylandDisplay(), size, QImage::Format_ARGB32);
+ attach(m_buffer);
+
+ int depth = XDefaultDepth(m_glxIntegration->xDisplay(), m_glxIntegration->screen());
+ m_pixmap = XCreatePixmap(m_glxIntegration->xDisplay(), m_glxIntegration->rootWindow(), size.width(), size.height(), depth);
+ XSync(m_glxIntegration->xDisplay(), False);
+
+ m_glxPixmap = glXCreatePixmap(m_glxIntegration->xDisplay(), m_config, m_pixmap,0);
+
+ if (!m_glxPixmap)
+ qDebug() << "Could not make glx surface out of pixmap :(";
}
+
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.h b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.h
index 3f20a0e..60b22a4 100644
--- a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.h
+++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.h
@@ -52,14 +52,23 @@ public:
QWaylandReadbackGlxWindow(QWindow *window, QWaylandReadbackGlxIntegration *glxIntegration);
WindowType windowType() const;
- QPlatformGLContext *glContext() const;
+ QPlatformGLSurface *createGLSurface() const;
void setGeometry(const QRect &rect);
+ Pixmap glxPixmap() const;
+
+ uchar *buffer();
+
private:
- QWaylandReadbackGlxIntegration *mGlxIntegration;
- QWaylandReadbackGlxContext *mContext;
+ void createSurface();
+
+ QWaylandReadbackGlxIntegration *m_glxIntegration;
+ QWaylandShmBuffer *m_buffer;
+ Pixmap m_pixmap;
+ GLXFBConfig m_config;
+ GLXPixmap m_glxPixmap;
};
#endif // QWAYLANDREADBACKGLXWINDOW_H
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.cpp
index e61ee69..08b6f76 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.cpp
@@ -42,127 +42,37 @@
#include "qwaylandxcompositeeglcontext.h"
#include "qwaylandxcompositeeglwindow.h"
-#include "qwaylandxcompositebuffer.h"
-#include "wayland-xcomposite-client-protocol.h"
#include <QtCore/QDebug>
#include <QtGui/QRegion>
#include "qeglconvenience.h"
-#include "qxlibeglintegration.h"
-#include <X11/extensions/Xcomposite.h>
-
-QWaylandXCompositeEGLContext::QWaylandXCompositeEGLContext(QWaylandXCompositeEGLIntegration *glxIntegration, QWaylandXCompositeEGLWindow *window)
- : QPlatformGLContext()
- , mEglIntegration(glxIntegration)
- , mWindow(window)
- , mBuffer(0)
- , mXWindow(0)
- , mConfig(q_configFromQWindowFormat(glxIntegration->eglDisplay(),window->window()->requestedWindowFormat(),true,EGL_WINDOW_BIT))
- , mWaitingForSync(false)
-{
- QVector<EGLint> eglContextAttrs;
- eglContextAttrs.append(EGL_CONTEXT_CLIENT_VERSION); eglContextAttrs.append(2);
- eglContextAttrs.append(EGL_NONE);
-
- mContext = eglCreateContext(glxIntegration->eglDisplay(),mConfig,EGL_NO_CONTEXT,eglContextAttrs.constData());
- if (mContext == EGL_NO_CONTEXT) {
- qFatal("failed to find context");
- }
-
- geometryChanged();
-}
-
-void QWaylandXCompositeEGLContext::makeCurrent()
+QWaylandXCompositeEGLSurface::QWaylandXCompositeEGLSurface(QWaylandXCompositeEGLWindow *window)
+ : QEGLSurface(window->eglSurface(), window->window()->glFormat())
+ , m_window(window)
{
- eglMakeCurrent(mEglIntegration->eglDisplay(),mEglWindowSurface,mEglWindowSurface,mContext);
}
-void QWaylandXCompositeEGLContext::doneCurrent()
+EGLSurface QWaylandXCompositeEGLSurface::eglSurface() const
{
- QPlatformGLContext::doneCurrent();
- eglMakeCurrent(mEglIntegration->eglDisplay(),EGL_NO_SURFACE,EGL_NO_SURFACE,EGL_NO_CONTEXT);
+ return m_window->eglSurface();
}
-void QWaylandXCompositeEGLContext::swapBuffers()
+QWaylandXCompositeEGLContext::QWaylandXCompositeEGLContext(const QGuiGLFormat &format, QPlatformGLContext *share, EGLDisplay display)
+ : QEGLPlatformContext(format, share, display)
{
- QSize size = mWindow->geometry().size();
-
- eglSwapBuffers(mEglIntegration->eglDisplay(),mEglWindowSurface);
- mWindow->damage(QRegion(QRect(QPoint(0,0),size)));
- mWindow->waitForFrameSync();
-}
-
-void * QWaylandXCompositeEGLContext::getProcAddress(const QString &procName)
-{
- return (void *)eglGetProcAddress(qPrintable(procName));
}
-QWindowFormat QWaylandXCompositeEGLContext::windowFormat() const
+void QWaylandXCompositeEGLContext::swapBuffers(const QPlatformGLSurface &surface)
{
- return q_windowFormatFromConfig(mEglIntegration->eglDisplay(),mConfig);
-}
-
-void QWaylandXCompositeEGLContext::sync_function(void *data)
-{
- QWaylandXCompositeEGLContext *that = static_cast<QWaylandXCompositeEGLContext *>(data);
- that->mWaitingForSync = false;
-}
-
-void QWaylandXCompositeEGLContext::geometryChanged()
-{
- QSize size(mWindow->geometry().size());
- if (size.isEmpty()) {
- //QGLWidget wants a context for a window without geometry
- size = QSize(1,1);
- }
-
- delete mBuffer;
- //XFreePixmap deletes the glxPixmap as well
- if (mXWindow) {
- XDestroyWindow(mEglIntegration->xDisplay(),mXWindow);
- }
-
- VisualID visualId = QXlibEglIntegration::getCompatibleVisualId(mEglIntegration->xDisplay(),mEglIntegration->eglDisplay(),mConfig);
-
- XVisualInfo visualInfoTemplate;
- memset(&visualInfoTemplate, 0, sizeof(XVisualInfo));
- visualInfoTemplate.visualid = visualId;
-
- int matchingCount = 0;
- XVisualInfo *visualInfo = XGetVisualInfo(mEglIntegration->xDisplay(), VisualIDMask, &visualInfoTemplate, &matchingCount);
-
- Colormap cmap = XCreateColormap(mEglIntegration->xDisplay(),mEglIntegration->rootWindow(),visualInfo->visual,AllocNone);
-
- XSetWindowAttributes a;
- a.colormap = cmap;
- mXWindow = XCreateWindow(mEglIntegration->xDisplay(), mEglIntegration->rootWindow(),0, 0, size.width(), size.height(),
- 0, visualInfo->depth, InputOutput, visualInfo->visual,
- CWColormap, &a);
-
- XCompositeRedirectWindow(mEglIntegration->xDisplay(), mXWindow, CompositeRedirectManual);
- XMapWindow(mEglIntegration->xDisplay(), mXWindow);
+ QEGLPlatformContext::swapBuffers(surface);
- mEglWindowSurface = eglCreateWindowSurface(mEglIntegration->eglDisplay(),mConfig,mXWindow,0);
- if (mEglWindowSurface == EGL_NO_SURFACE) {
- qFatal("Could not make eglsurface");
- }
+ const QWaylandXCompositeEGLSurface &s =
+ static_cast<const QWaylandXCompositeEGLSurface &>(surface);
- XSync(mEglIntegration->xDisplay(),False);
- mBuffer = new QWaylandXCompositeBuffer(mEglIntegration->waylandXComposite(),
- (uint32_t)mXWindow,
- size,
- mEglIntegration->waylandDisplay()->argbVisual());
- mWindow->attach(mBuffer);
- wl_display_sync_callback(mEglIntegration->waylandDisplay()->wl_display(),
- QWaylandXCompositeEGLContext::sync_function,
- this);
+ QSize size = s.window()->geometry().size();
- mWaitingForSync = true;
- wl_display_sync(mEglIntegration->waylandDisplay()->wl_display(),0);
- mEglIntegration->waylandDisplay()->flushRequests();
- while (mWaitingForSync) {
- mEglIntegration->waylandDisplay()->readEvents();
- }
+ s.window()->damage(QRect(QPoint(), size));
+ s.window()->waitForFrameSync();
}
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.h
index 528faf0..bd7039f 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.h
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.h
@@ -44,37 +44,29 @@
#include <QtGui/QPlatformGLContext>
-#include "qwaylandbuffer.h"
#include "qwaylandxcompositeeglintegration.h"
+#include "qeglplatformcontext.h"
+
class QWaylandXCompositeEGLWindow;
-class QWaylandXCompositeEGLContext : public QPlatformGLContext
+class QWaylandXCompositeEGLSurface : public QEGLSurface
{
public:
- QWaylandXCompositeEGLContext(QWaylandXCompositeEGLIntegration *glxIntegration, QWaylandXCompositeEGLWindow *window);
-
- void makeCurrent();
- void doneCurrent();
- void swapBuffers();
- void* getProcAddress(const QString& procName);
-
- QWindowFormat windowFormat() const;
-
- void geometryChanged();
+ QWaylandXCompositeEGLSurface(QWaylandXCompositeEGLWindow *window);
+ EGLSurface eglSurface() const;
+ QWaylandXCompositeEGLWindow *window() const { return m_window; }
private:
- QWaylandXCompositeEGLIntegration *mEglIntegration;
- QWaylandXCompositeEGLWindow *mWindow;
- QWaylandBuffer *mBuffer;
+ QWaylandXCompositeEGLWindow *m_window;
+};
- Window mXWindow;
- EGLConfig mConfig;
- EGLContext mContext;
- EGLSurface mEglWindowSurface;
+class QWaylandXCompositeEGLContext : public QEGLPlatformContext
+{
+public:
+ QWaylandXCompositeEGLContext(const QGuiGLFormat &format, QPlatformGLContext *share, EGLDisplay display);
- static void sync_function(void *data);
- bool mWaitingForSync;
+ void swapBuffers(const QPlatformGLSurface &surface);
};
#endif // QWAYLANDXCOMPOSITEEGLCONTEXT_H
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.cpp
index 239ec89..90d5bea 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.cpp
@@ -75,6 +75,11 @@ QWaylandWindow * QWaylandXCompositeEGLIntegration::createEglWindow(QWindow *wind
return new QWaylandXCompositeEGLWindow(window,this);
}
+QPlatformGLContext *QWaylandXCompositeEGLIntegration::createPlatformGLContext(const QGuiGLFormat &glFormat, QPlatformGLContext *share) const
+{
+ return new QWaylandXCompositeEGLContext(glFormat, share, eglDisplay());
+}
+
Display * QWaylandXCompositeEGLIntegration::xDisplay() const
{
return mDisplay;
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.h
index 3252ce7..ac302ef 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.h
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.h
@@ -51,6 +51,8 @@
#include <QtCore/QVariant>
#include <QtGui/QWindow>
+#include <QPlatformGLContext>
+
#include <QWaitCondition>
#include <X11/Xlib.h>
@@ -67,6 +69,7 @@ public:
void initialize();
QWaylandWindow *createEglWindow(QWindow *window);
+ QPlatformGLContext *createPlatformGLContext(const QGuiGLFormat &glFormat, QPlatformGLContext *share) const;
QWaylandDisplay *waylandDisplay() const;
struct wl_xcomposite *waylandXComposite() const;
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp
index e57203f..5c6717e 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp
@@ -40,15 +40,27 @@
****************************************************************************/
#include "qwaylandxcompositeeglwindow.h"
+#include "qwaylandxcompositebuffer.h"
+
+#include "qeglconvenience.h"
+
+#include "wayland-xcomposite-client-protocol.h"
+#include "qxlibeglintegration.h"
+
+#include <X11/extensions/Xcomposite.h>
#include <QtCore/QDebug>
QWaylandXCompositeEGLWindow::QWaylandXCompositeEGLWindow(QWindow *window, QWaylandXCompositeEGLIntegration *glxIntegration)
: QWaylandWindow(window)
- , mGlxIntegration(glxIntegration)
- , mContext(0)
+ , m_glxIntegration(glxIntegration)
+ , m_context(0)
+ , m_buffer(0)
+ , m_xWindow(0)
+ , m_config(q_configFromGLFormat(glxIntegration->eglDisplay(), window->glFormat(), true))
+ , m_surface(0)
+ , m_waitingForSync(false)
{
-
}
QWaylandWindow::WindowType QWaylandXCompositeEGLWindow::windowType() const
@@ -57,21 +69,86 @@ QWaylandWindow::WindowType QWaylandXCompositeEGLWindow::windowType() const
return QWaylandWindow::Egl;
}
-QPlatformGLContext * QWaylandXCompositeEGLWindow::glContext() const
+QPlatformGLSurface *QWaylandXCompositeEGLWindow::createGLSurface() const
{
- if (!mContext) {
- qDebug() << "creating glcontext;";
- QWaylandXCompositeEGLWindow *that = const_cast<QWaylandXCompositeEGLWindow *>(this);
- that->mContext = new QWaylandXCompositeEGLContext(mGlxIntegration,that);
- }
- return mContext;
+ return new QWaylandXCompositeEGLSurface(const_cast<QWaylandXCompositeEGLWindow *>(this));
}
void QWaylandXCompositeEGLWindow::setGeometry(const QRect &rect)
{
QWaylandWindow::setGeometry(rect);
- if (mContext) {
- mContext->geometryChanged();
+ if (m_surface) {
+ eglDestroySurface(m_glxIntegration->eglDisplay(), m_surface);
+ m_surface = 0;
+ }
+}
+
+EGLSurface QWaylandXCompositeEGLWindow::eglSurface() const
+{
+ if (!m_surface)
+ const_cast<QWaylandXCompositeEGLWindow *>(this)->createEglSurface();
+ return m_surface;
+}
+
+void QWaylandXCompositeEGLWindow::createEglSurface()
+{
+ QSize size(geometry().size());
+ if (size.isEmpty()) {
+ // QGLWidget wants a context for a window without geometry
+ size = QSize(1,1);
+ }
+
+ delete m_buffer;
+ //XFreePixmap deletes the glxPixmap as well
+ if (m_xWindow) {
+ XDestroyWindow(m_glxIntegration->xDisplay(), m_xWindow);
}
+
+ VisualID visualId = QXlibEglIntegration::getCompatibleVisualId(m_glxIntegration->xDisplay(), m_glxIntegration->eglDisplay(), m_config);
+
+ XVisualInfo visualInfoTemplate;
+ memset(&visualInfoTemplate, 0, sizeof(XVisualInfo));
+ visualInfoTemplate.visualid = visualId;
+
+ int matchingCount = 0;
+ XVisualInfo *visualInfo = XGetVisualInfo(m_glxIntegration->xDisplay(), VisualIDMask, &visualInfoTemplate, &matchingCount);
+
+ Colormap cmap = XCreateColormap(m_glxIntegration->xDisplay(),m_glxIntegration->rootWindow(),visualInfo->visual,AllocNone);
+
+ XSetWindowAttributes a;
+ a.colormap = cmap;
+ m_xWindow = XCreateWindow(m_glxIntegration->xDisplay(), m_glxIntegration->rootWindow(),0, 0, size.width(), size.height(),
+ 0, visualInfo->depth, InputOutput, visualInfo->visual,
+ CWColormap, &a);
+
+ XCompositeRedirectWindow(m_glxIntegration->xDisplay(), m_xWindow, CompositeRedirectManual);
+ XMapWindow(m_glxIntegration->xDisplay(), m_xWindow);
+
+ m_surface = eglCreateWindowSurface(m_glxIntegration->eglDisplay(), m_config, m_xWindow,0);
+ if (m_surface == EGL_NO_SURFACE) {
+ qFatal("Could not make eglsurface");
+ }
+
+ XSync(m_glxIntegration->xDisplay(),False);
+ mBuffer = new QWaylandXCompositeBuffer(m_glxIntegration->waylandXComposite(),
+ (uint32_t)m_xWindow,
+ size,
+ m_glxIntegration->waylandDisplay()->argbVisual());
+ attach(m_buffer);
+ wl_display_sync_callback(m_glxIntegration->waylandDisplay()->wl_display(),
+ QWaylandXCompositeEGLWindow::sync_function,
+ this);
+
+ m_waitingForSync = true;
+ wl_display_sync(m_glxIntegration->waylandDisplay()->wl_display(),0);
+ m_glxIntegration->waylandDisplay()->flushRequests();
+ while (m_waitingForSync)
+ m_glxIntegration->waylandDisplay()->readEvents();
+}
+
+void QWaylandXCompositeEGLWindow::sync_function(void *data)
+{
+ QWaylandXCompositeEGLWindow *that = static_cast<QWaylandXCompositeEGLWindow *>(data);
+ that->m_waitingForSync = false;
}
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.h
index 6efe556..16188ca 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.h
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.h
@@ -43,6 +43,8 @@
#define QWAYLANDXCOMPOSITEEGLWINDOW_H
#include "qwaylandwindow.h"
+#include "qwaylandbuffer.h"
+
#include "qwaylandxcompositeeglintegration.h"
#include "qwaylandxcompositeeglcontext.h"
@@ -52,14 +54,26 @@ public:
QWaylandXCompositeEGLWindow(QWindow *window, QWaylandXCompositeEGLIntegration *glxIntegration);
WindowType windowType() const;
- QPlatformGLContext *glContext() const;
+ QPlatformGLSurface *createGLSurface() const;
void setGeometry(const QRect &rect);
+ EGLSurface eglSurface() const;
+
private:
- QWaylandXCompositeEGLIntegration *mGlxIntegration;
- QWaylandXCompositeEGLContext *mContext;
+ void createEglSurface();
+
+ QWaylandXCompositeEGLIntegration *m_glxIntegration;
+ QWaylandXCompositeEGLContext *m_context;
+ QWaylandBuffer *m_buffer;
+
+ Window m_xWindow;
+ EGLConfig m_config;
+ EGLSurface m_surface;
+
+ bool m_waitingForSync;
+ static void sync_function(void *data);
};
#endif // QWAYLANDXCOMPOSITEEGLWINDOW_H
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/xcomposite_egl.pri b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/xcomposite_egl.pri
index 7d2f8ad..a61391b 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/xcomposite_egl.pri
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/xcomposite_egl.pri
@@ -1,5 +1,6 @@
include (../xcomposite_share/xcomposite_share.pri)
load(qpa/egl/convenience)
+load(qpa/egl/context)
load(qpa/egl/xlibintegration)
LIBS += -lXcomposite -lEGL
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.cpp
index aa26971..5d4cf7a 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.cpp
@@ -39,114 +39,67 @@
**
****************************************************************************/
+#include <QtCore/QDebug>
+
#include "qwaylandxcompositeglxcontext.h"
#include "qwaylandxcompositeglxwindow.h"
-#include "qwaylandxcompositebuffer.h"
-#include "wayland-xcomposite-client-protocol.h"
-#include <QtCore/QDebug>
-#include <QtGui/QRegion>
-
-#include <X11/extensions/Xcomposite.h>
-
-QWaylandXCompositeGLXContext::QWaylandXCompositeGLXContext(QWaylandXCompositeGLXIntegration *glxIntegration, QWaylandXCompositeGLXWindow *window)
- : QPlatformGLContext()
- , mGlxIntegration(glxIntegration)
- , mWindow(window)
- , mBuffer(0)
- , mXWindow(0)
- , mConfig(qglx_findConfig(glxIntegration->xDisplay(),glxIntegration->screen(),window->window()->requestedWindowFormat()))
- , mWaitingForSyncCallback(false)
-{
- XVisualInfo *visualInfo = glXGetVisualFromFBConfig(glxIntegration->xDisplay(),mConfig);
- mContext = glXCreateContext(glxIntegration->xDisplay(),visualInfo,0,TRUE);
+#include <QRegion>
- geometryChanged();
-}
-
-void QWaylandXCompositeGLXContext::makeCurrent()
+QWaylandXCompositeGLXSurface::QWaylandXCompositeGLXSurface(QWaylandXCompositeGLXWindow *window)
+ : m_window(window)
{
- glXMakeCurrent(mGlxIntegration->xDisplay(),mXWindow,mContext);
}
-void QWaylandXCompositeGLXContext::doneCurrent()
+Window QWaylandXCompositeGLXSurface::xWindow() const
{
- glXMakeCurrent(mGlxIntegration->xDisplay(),0,0);
- QPlatformGLContext::doneCurrent();
+ return m_window->xWindow();
}
-void QWaylandXCompositeGLXContext::swapBuffers()
+QWaylandXCompositeGLXContext::QWaylandXCompositeGLXContext(const QGuiGLFormat &format, QPlatformGLContext *share, Display *display, int screen)
+ : m_display(display)
{
- QSize size = mWindow->geometry().size();
+ GLXContext shareContext = share ? static_cast<QWaylandXCompositeGLXContext *>(share)->m_context : 0;
- glXSwapBuffers(mGlxIntegration->xDisplay(),mXWindow);
- mWindow->damage(QRegion(QRect(QPoint(0,0),size)));
- mWindow->waitForFrameSync();
+ GLXFBConfig config = qglx_findConfig(display, screen, format);
+ XVisualInfo *visualInfo = glXGetVisualFromFBConfig(display, config);
+ m_context = glXCreateContext(display, visualInfo, shareContext, true);
+ m_format = qglx_guiGLFormatFromGLXFBConfig(display, config, m_context);
}
-void * QWaylandXCompositeGLXContext::getProcAddress(const QString &procName)
+bool QWaylandXCompositeGLXContext::makeCurrent(const QPlatformGLSurface &surface)
{
- return (void *) glXGetProcAddress(reinterpret_cast<GLubyte *>(procName.toLatin1().data()));
+ Window xWindow = static_cast<const QWaylandXCompositeGLXSurface &>(surface).xWindow();
+
+ return glXMakeCurrent(m_display, xWindow, m_context);
}
-QWindowFormat QWaylandXCompositeGLXContext::windowFormat() const
+void QWaylandXCompositeGLXContext::doneCurrent()
{
- return qglx_platformWindowFromGLXFBConfig(mGlxIntegration->xDisplay(),mConfig,mContext);
+ glXMakeCurrent(m_display, 0, 0);
}
-void QWaylandXCompositeGLXContext::sync_function(void *data)
+void QWaylandXCompositeGLXContext::swapBuffers(const QPlatformGLSurface &surface)
{
- QWaylandXCompositeGLXContext *that = static_cast<QWaylandXCompositeGLXContext *>(data);
- that->mWaitingForSyncCallback = false;
+ const QWaylandXCompositeGLXSurface &s =
+ static_cast<const QWaylandXCompositeGLXSurface &>(surface);
+
+ QSize size = s.window()->geometry().size();
+
+ glXSwapBuffers(m_display, s.xWindow());
+
+ s.window()->damage(QRect(QPoint(), size));
+ s.window()->waitForFrameSync();
}
-void QWaylandXCompositeGLXContext::waitForSync()
+void (*QWaylandXCompositeGLXContext::getProcAddress(const QByteArray &procName)) ()
{
- wl_display_sync_callback(mGlxIntegration->waylandDisplay()->wl_display(),
- QWaylandXCompositeGLXContext::sync_function,
- this);
- mWaitingForSyncCallback = true;
- wl_display_sync(mGlxIntegration->waylandDisplay()->wl_display(),0);
- mGlxIntegration->waylandDisplay()->flushRequests();
- while (mWaitingForSyncCallback) {
- mGlxIntegration->waylandDisplay()->readEvents();
- }
+ return glXGetProcAddress(reinterpret_cast<const GLubyte *>(procName.constData()));
}
-void QWaylandXCompositeGLXContext::geometryChanged()
+QGuiGLFormat QWaylandXCompositeGLXContext::format() const
{
- QSize size(mWindow->geometry().size());
- if (size.isEmpty()) {
- //QGLWidget wants a context for a window without geometry
- size = QSize(1,1);
- }
-
- delete mBuffer;
- //XFreePixmap deletes the glxPixmap as well
- if (mXWindow) {
- XDestroyWindow(mGlxIntegration->xDisplay(),mXWindow);
- }
-
- XVisualInfo *visualInfo = glXGetVisualFromFBConfig(mGlxIntegration->xDisplay(),mConfig);
- Colormap cmap = XCreateColormap(mGlxIntegration->xDisplay(),mGlxIntegration->rootWindow(),visualInfo->visual,AllocNone);
-
- XSetWindowAttributes a;
- a.background_pixel = WhitePixel(mGlxIntegration->xDisplay(), mGlxIntegration->screen());
- a.border_pixel = BlackPixel(mGlxIntegration->xDisplay(), mGlxIntegration->screen());
- a.colormap = cmap;
- mXWindow = XCreateWindow(mGlxIntegration->xDisplay(), mGlxIntegration->rootWindow(),0, 0, size.width(), size.height(),
- 0, visualInfo->depth, InputOutput, visualInfo->visual,
- CWBackPixel|CWBorderPixel|CWColormap, &a);
-
- XCompositeRedirectWindow(mGlxIntegration->xDisplay(), mXWindow, CompositeRedirectManual);
- XMapWindow(mGlxIntegration->xDisplay(), mXWindow);
-
- XSync(mGlxIntegration->xDisplay(),False);
- mBuffer = new QWaylandXCompositeBuffer(mGlxIntegration->waylandXComposite(),
- (uint32_t)mXWindow,
- size,
- mGlxIntegration->waylandDisplay()->argbVisual());
- mWindow->attach(mBuffer);
- waitForSync();
+ return m_format;
}
+
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.h
index 49ae73d..e0de801 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.h
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.h
@@ -44,42 +44,44 @@
#include <QtGui/QPlatformGLContext>
-#include <QtCore/QWaitCondition>
-
-#include "qwaylandbuffer.h"
#include "qwaylandxcompositeglxintegration.h"
-
#include "qglxconvenience.h"
class QWaylandXCompositeGLXWindow;
class QWaylandShmBuffer;
+class QWaylandXCompositeGLXSurface : public QPlatformGLSurface
+{
+public:
+ QWaylandXCompositeGLXSurface(QWaylandXCompositeGLXWindow *window);
+
+ QWaylandXCompositeGLXWindow *window() const { return m_window; }
+ Window xWindow() const;
+
+private:
+ QWaylandXCompositeGLXWindow *m_window;
+};
+
+
class QWaylandXCompositeGLXContext : public QPlatformGLContext
{
public:
- QWaylandXCompositeGLXContext(QWaylandXCompositeGLXIntegration *glxIntegration, QWaylandXCompositeGLXWindow *window);
+ QWaylandXCompositeGLXContext(const QGuiGLFormat &format, QPlatformGLContext *share, Display *display, int screen);
- void makeCurrent();
- void doneCurrent();
- void swapBuffers();
- void* getProcAddress(const QString& procName);
+ QGuiGLFormat format() const;
- QWindowFormat windowFormat() const;
+ void swapBuffers(const QPlatformGLSurface &surface);
- void geometryChanged();
+ bool makeCurrent(const QPlatformGLSurface &surface);
+ void doneCurrent();
-private:
- QWaylandXCompositeGLXIntegration *mGlxIntegration;
- QWaylandXCompositeGLXWindow *mWindow;
- QWaylandBuffer *mBuffer;
+ void (*getProcAddress(const QByteArray &procName)) ();
- Window mXWindow;
- GLXFBConfig mConfig;
- GLXContext mContext;
+private:
+ GLXContext m_context;
- static void sync_function(void *data);
- void waitForSync();
- bool mWaitingForSyncCallback;
+ Display *m_display;
+ QGuiGLFormat m_format;
};
#endif // QWAYLANDXCOMPOSITEGLXCONTEXT_H
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.cpp
index e5f4feb..a80a595 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.cpp
@@ -72,7 +72,12 @@ void QWaylandXCompositeGLXIntegration::initialize()
QWaylandWindow * QWaylandXCompositeGLXIntegration::createEglWindow(QWindow *window)
{
- return new QWaylandXCompositeGLXWindow(window,this);
+ return new QWaylandXCompositeGLXWindow(window, this);
+}
+
+QPlatformGLContext *QWaylandXCompositeGLXIntegration::createPlatformGLContext(const QGuiGLFormat &glFormat, QPlatformGLContext *share) const
+{
+ return new QWaylandXCompositeGLXContext(glFormat, share, mDisplay, mScreen);
}
Display * QWaylandXCompositeGLXIntegration::xDisplay() const
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.h
index f934a9a..c347b11 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.h
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.h
@@ -64,6 +64,7 @@ public:
void initialize();
QWaylandWindow *createEglWindow(QWindow *window);
+ QPlatformGLContext *createPlatformGLContext(const QGuiGLFormat &glFormat, QPlatformGLContext *share) const;
QWaylandDisplay *waylandDisplay() const;
struct wl_xcomposite *waylandXComposite() const;
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.cpp
index 6eec1d4..41a14e3 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.cpp
@@ -40,15 +40,24 @@
****************************************************************************/
#include "qwaylandxcompositeglxwindow.h"
+#include "qwaylandxcompositebuffer.h"
#include <QtCore/QDebug>
+#include "wayland-xcomposite-client-protocol.h"
+#include <QtGui/QRegion>
+
+#include <X11/extensions/Xcomposite.h>
+
+
QWaylandXCompositeGLXWindow::QWaylandXCompositeGLXWindow(QWindow *window, QWaylandXCompositeGLXIntegration *glxIntegration)
: QWaylandWindow(window)
- , mGlxIntegration(glxIntegration)
- , mContext(0)
+ , m_glxIntegration(glxIntegration)
+ , m_xWindow(0)
+ , m_config(qglx_findConfig(glxIntegration->xDisplay(), glxIntegration->screen(), window->glFormat()))
+ , m_buffer(0)
+ , m_waitingForSync(false)
{
-
}
QWaylandWindow::WindowType QWaylandXCompositeGLXWindow::windowType() const
@@ -57,21 +66,79 @@ QWaylandWindow::WindowType QWaylandXCompositeGLXWindow::windowType() const
return QWaylandWindow::Egl;
}
-QPlatformGLContext * QWaylandXCompositeGLXWindow::glContext() const
+QPlatformGLSurface *QWaylandXCompositeGLXWindow::createGLSurface() const
{
- if (!mContext) {
- qDebug() << "creating glcontext;";
- QWaylandXCompositeGLXWindow *that = const_cast<QWaylandXCompositeGLXWindow *>(this);
- that->mContext = new QWaylandXCompositeGLXContext(mGlxIntegration,that);
- }
- return mContext;
+ return new QWaylandXCompositeGLXSurface(const_cast<QWaylandXCompositeGLXWindow *>(this));
}
void QWaylandXCompositeGLXWindow::setGeometry(const QRect &rect)
{
QWaylandWindow::setGeometry(rect);
- if (mContext) {
- mContext->geometryChanged();
+ if (m_xWindow) {
+ delete m_buffer;
+
+ XDestroyWindow(m_glxIntegration->xDisplay(), m_xWindow);
+ m_xWindow = 0;
+ }
+}
+
+Window QWaylandXCompositeGLXWindow::xWindow() const
+{
+ if (!m_xWindow)
+ const_cast<QWaylandXCompositeGLXWindow *>(this)->createSurface();
+
+ return m_xWindow;
+}
+
+void QWaylandXCompositeGLXWindow::waitForSync()
+{
+ wl_display_sync_callback(m_glxIntegration->waylandDisplay()->wl_display(),
+ QWaylandXCompositeGLXWindow::sync_function,
+ this);
+ m_waitingForSync= true;
+ wl_display_sync(m_glxIntegration->waylandDisplay()->wl_display(), 0);
+ m_glxIntegration->waylandDisplay()->flushRequests();
+ while (m_waitingForSync)
+ m_glxIntegration->waylandDisplay()->readEvents();
+}
+
+
+void QWaylandXCompositeGLXWindow::createSurface()
+{
+ QSize size(geometry().size());
+ if (size.isEmpty()) {
+ //QGLWidget wants a context for a window without geometry
+ size = QSize(1,1);
}
+
+ XVisualInfo *visualInfo = glXGetVisualFromFBConfig(m_glxIntegration->xDisplay(), m_config);
+ Colormap cmap = XCreateColormap(m_glxIntegration->xDisplay(), m_glxIntegration->rootWindow(),
+ visualInfo->visual, AllocNone);
+
+ XSetWindowAttributes a;
+ a.background_pixel = WhitePixel(m_glxIntegration->xDisplay(), m_glxIntegration->screen());
+ a.border_pixel = BlackPixel(m_glxIntegration->xDisplay(), m_glxIntegration->screen());
+ a.colormap = cmap;
+ m_xWindow = XCreateWindow(m_glxIntegration->xDisplay(), m_glxIntegration->rootWindow(),0, 0, size.width(), size.height(),
+ 0, visualInfo->depth, InputOutput, visualInfo->visual,
+ CWBackPixel|CWBorderPixel|CWColormap, &a);
+
+ XCompositeRedirectWindow(m_glxIntegration->xDisplay(), m_xWindow, CompositeRedirectManual);
+ XMapWindow(m_glxIntegration->xDisplay(), m_xWindow);
+
+ XSync(m_glxIntegration->xDisplay(), False);
+ m_buffer = new QWaylandXCompositeBuffer(m_glxIntegration->waylandXComposite(),
+ (uint32_t)m_xWindow,
+ size,
+ m_glxIntegration->waylandDisplay()->argbVisual());
+ attach(m_buffer);
+ waitForSync();
+}
+
+void QWaylandXCompositeGLXWindow::sync_function(void *data)
+{
+ QWaylandXCompositeGLXWindow *that = static_cast<QWaylandXCompositeGLXWindow *>(data);
+ that->m_waitingForSync = false;
}
+
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.h
index 3305c12..7a19c71 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.h
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.h
@@ -46,20 +46,36 @@
#include "qwaylandxcompositeglxintegration.h"
#include "qwaylandxcompositeglxcontext.h"
+#include <QtCore/QWaitCondition>
+
+#include "qwaylandbuffer.h"
+
class QWaylandXCompositeGLXWindow : public QWaylandWindow
{
public:
QWaylandXCompositeGLXWindow(QWindow *window, QWaylandXCompositeGLXIntegration *glxIntegration);
WindowType windowType() const;
- QPlatformGLContext *glContext() const;
+ QPlatformGLSurface *createGLSurface() const;
void setGeometry(const QRect &rect);
+ Window xWindow() const;
+
private:
- QWaylandXCompositeGLXIntegration *mGlxIntegration;
- QWaylandXCompositeGLXContext *mContext;
+ void createSurface();
+
+ QWaylandXCompositeGLXIntegration *m_glxIntegration;
+
+ Window m_xWindow;
+ GLXFBConfig m_config;
+
+ QWaylandBuffer *m_buffer;
+
+ void waitForSync();
+ bool m_waitingForSync;
+ static void sync_function(void *data);
};
#endif // QWAYLANDXCOMPOSITEGLXWINDOW_H
diff --git a/src/plugins/platforms/wayland/qwaylandintegration.cpp b/src/plugins/platforms/wayland/qwaylandintegration.cpp
index 9aa512b..226bfd4 100644
--- a/src/plugins/platforms/wayland/qwaylandintegration.cpp
+++ b/src/plugins/platforms/wayland/qwaylandintegration.cpp
@@ -51,7 +51,7 @@
#include <QtGui/QWindowSystemInterface>
#include <QtGui/QPlatformCursor>
-#include <QtGui/QWindowFormat>
+#include <QtGui/QGuiGLFormat>
#include <QtGui/private/qpixmap_raster_p.h>
#ifdef QT_WAYLAND_GL_SUPPORT
@@ -108,6 +108,14 @@ QPlatformWindow *QWaylandIntegration::createPlatformWindow(QWindow *window) cons
return new QWaylandShmWindow(window);
}
+QPlatformGLContext *QWaylandIntegration::createPlatformGLContext(const QGuiGLFormat &glFormat, QPlatformGLContext *share) const
+{
+#ifdef QT_WAYLAND_GL_SUPPORT
+ return mDisplay->eglIntegration()->createPlatformGLContext(glFormat, share);
+#endif
+ return 0;
+}
+
QWindowSurface *QWaylandIntegration::createWindowSurface(QWindow *window, WId winId) const
{
Q_UNUSED(winId);
diff --git a/src/plugins/platforms/wayland/qwaylandintegration.h b/src/plugins/platforms/wayland/qwaylandintegration.h
index 1ca468c..2e05faf 100644
--- a/src/plugins/platforms/wayland/qwaylandintegration.h
+++ b/src/plugins/platforms/wayland/qwaylandintegration.h
@@ -57,6 +57,7 @@ public:
bool hasCapability(QPlatformIntegration::Capability cap) const;
QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
QPlatformWindow *createPlatformWindow(QWindow *window) const;
+ QPlatformGLContext *createPlatformGLContext(const QGuiGLFormat &glFormat, QPlatformGLContext *share) const;
QWindowSurface *createWindowSurface(QWindow *window, WId winId) const;
QList<QPlatformScreen *> screens() const;
diff --git a/src/plugins/platforms/wayland/qwaylandshmwindow.cpp b/src/plugins/platforms/wayland/qwaylandshmwindow.cpp
index 087139e..bd1e61f 100644
--- a/src/plugins/platforms/wayland/qwaylandshmwindow.cpp
+++ b/src/plugins/platforms/wayland/qwaylandshmwindow.cpp
@@ -63,9 +63,9 @@ QWaylandWindow::WindowType QWaylandShmWindow::windowType() const
return QWaylandWindow::Shm;
}
-QPlatformGLContext * QWaylandShmWindow::glContext() const
+QPlatformGLSurface * QWaylandShmWindow::glSurface() const
{
- qWarning("Trying to retrieve a glContext from a Raster window surface!");
+ qWarning("Raster window does not have a GL drawable");
return 0;
}
diff --git a/src/plugins/platforms/wayland/qwaylandshmwindow.h b/src/plugins/platforms/wayland/qwaylandshmwindow.h
index e964e0d..db26c5c 100644
--- a/src/plugins/platforms/wayland/qwaylandshmwindow.h
+++ b/src/plugins/platforms/wayland/qwaylandshmwindow.h
@@ -52,7 +52,7 @@ public:
~QWaylandShmWindow();
WindowType windowType() const;
- QPlatformGLContext *glContext() const;
+ QPlatformGLSurface *glSurface() const;
};
#endif // QWAYLANDSHMWINDOW_H